using Godot;

namespace MyCraft2;

public partial class FreedomCamera : Camera3D
{
    [Export] public float MoveSpeed = 0.1f;

    [Export] public float MouseSensitivity = 0.002f;

    [Export(PropertyHint.Range, "-89,89")] public float MaxPitchAngle = 89.0f;

    [Signal]
    public delegate void CameraMoveEventHandler(Vector3 position);

    [Export] public PositionLabel? PositionLabel;
    private float _cameraPitch;
    private Vector2 _cameraRotation;

    public override void _Ready()
    {
        Input.MouseMode = Input.MouseModeEnum.Captured;

        InputMapExtend.AddAction("move_forward", new InputEventKey { Keycode = Key.W });
        InputMapExtend.AddAction("move_back", new InputEventKey { Keycode = Key.S });
        InputMapExtend.AddAction("move_left", new InputEventKey { Keycode = Key.A });
        InputMapExtend.AddAction("move_right", new InputEventKey { Keycode = Key.D });

        InputMapExtend.AddAction("move_up", new InputEventKey { Keycode = Key.Space });
        InputMapExtend.AddAction("move_down", new InputEventKey { Keycode = Key.Shift });
    }

    public override void _Input(InputEvent @event)
    {
        if (Input.IsActionJustPressed("ui_cancel"))
            Input.MouseMode = Input.MouseMode == Input.MouseModeEnum.Captured
                ? Input.MouseModeEnum.Visible
                : Input.MouseModeEnum.Captured;

        if (Input.MouseMode is not Input.MouseModeEnum.Captured) return;

        if (@event is InputEventMouseMotion mouseMotion)
            RotateCamera(mouseMotion.Relative * MouseSensitivity);
    }

    public override void _Process(double delta)
    {
        if (Input.IsActionPressed("move_forward"))
            Translate(Vector3.Forward * MoveSpeed);
        if (Input.IsActionPressed("move_back"))
            Translate(Vector3.Back * MoveSpeed);
        if (Input.IsActionPressed("move_left"))
            Translate(Vector3.Left * MoveSpeed);
        if (Input.IsActionPressed("move_right"))
            Translate(Vector3.Right * MoveSpeed);

        if (Input.IsActionPressed("move_up"))
            Position = new Vector3(Position.X, Position.Y + MoveSpeed, Position.Z);
        if (Input.IsActionPressed("move_down"))
            Position = new Vector3(Position.X, Position.Y - MoveSpeed, Position.Z);


        EmitSignal(SignalName.CameraMove, Position);
        if(PositionLabel is not null)PositionLabel.PositionInText = Position;
    }

    // 相机旋转逻辑
    private void RotateCamera(Vector2 mouseDelta)
    {
        // 水平旋转（绕Y轴）
        RotateY(-mouseDelta.X);

        // 垂直旋转（绕X轴）
        _cameraPitch -= mouseDelta.Y;
        _cameraPitch = Mathf.Clamp(
            _cameraPitch,
            Mathf.DegToRad(-MaxPitchAngle),
            Mathf.DegToRad(MaxPitchAngle)
        );

        Rotation = new Vector3(
            _cameraPitch,
            Rotation.Y,
            Rotation.Z
        );
    }
}